package com.topfinance.payment.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.topfinance.frame.dao.HibernateEntityDao;
import com.topfinance.frame.exception.AppException;
import com.topfinance.frame.util.StringUtil;
import com.topfinance.frame.util.XmlHelper;
import com.topfinance.payment.ebo.TCfgFmt8583Ebo;
import com.topfinance.payment.ebo.TCfgFmtXmlEbo;
import com.topfinance.payment.ebo.TCfgFormatEbo;
import com.topfinance.payment.service.ITCfgFormatMgr;

/**
 * 该类自动实现了dao的一般方法，如add, remove, update
 * 在service中出现的大部分情况下是在向后台提交数据前的处理(如校验)及获取后台数据后的处理等
 * 
 * @author
 * 
 */

public class TCfgFormatMgrImpl extends HibernateEntityDao<TCfgFormatEbo> implements ITCfgFormatMgr {

	private static final Log log = LogFactory.getLog(TCfgFormatMgrImpl.class);

	// 获得传输协议
	public TCfgFormatEbo getTCfgFormat(Integer oid) throws AppException {
		return (TCfgFormatEbo) get(oid);
	}

	public void deleteTCfgFormat(Integer oid) throws AppException {
		removeById(TCfgFormatEbo.class, oid);
	}

	public void deleteTCfgFormat(TCfgFormatEbo o) throws AppException {
		// TODO Auto-generated method stub
		removeById(o.getClass(), o.getOid());
	}

	// 获得传输协议列表
	public List<TCfgFormatEbo> getAllFormat() throws AppException {
		String hql = " from TCfgFormatEbo t ";
		String where = "";
		List<Object> paramList = new ArrayList<Object>();
		if (isNotBlank(where)) {
			where = " where " + where;
		}
		hql = hql + where;
		System.out.println(hql+"hql");
		return find(hql, paramList.toArray());
	}

	// 获得格式协议及格式定义
	// fmtName=null返回所有的,返回多个用逗号间隔
	public String getFmtByXML(String fmtName) throws AppException {
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document document = builder.newDocument();
			document.setXmlVersion("1.0");
			org.w3c.dom.Element formatsNode = document.createElement("formats");
			document.appendChild(formatsNode);

			Criteria crtia = this.getSession().createCriteria(TCfgFormatEbo.class);
			if (fmtName != null) {
				StringTokenizer st = new StringTokenizer(fmtName, ",");
				String[] names = new String[st.countTokens()];
				int index = 0;
				if (st.hasMoreElements()) {
					names[index++] = st.nextElement().toString();
				}
				crtia.add(Restrictions.in("name", names));
			}
			List<TCfgFormatEbo> fmts = crtia.list();
			for (TCfgFormatEbo fmt : fmts) {
				org.w3c.dom.Element formatNode = document.createElement("format");
				formatNode.setAttribute("name", fmt.getName());
				// formatNode.setAttribute("type", fmt.getType());
				formatNode.setAttribute("fmtver", fmt.getFmtver());
				formatNode.setAttribute("description", fmt.getDescription());
				formatNode.setAttribute("delim", fmt.getDelim());
				formatNode.setAttribute("format", fmt.getFormat());
				// formatNode.setAttribute("pathOpid", fmt.getPathOpid());
				// formatNode.setAttribute("config", fmt.getConfig());
				formatsNode.appendChild(formatNode);
				org.w3c.dom.Element fmtsNode = document.createElement("fmts");
				formatNode.appendChild(fmtsNode);
				Criteria crtia8583 = this.getSession().createCriteria(TCfgFmt8583Ebo.class);
				crtia8583.add(Restrictions.eq("TCfgFormat.oid", fmt.getOid()));
				List<TCfgFmt8583Ebo> fmt8583s = crtia8583.list();
				for (TCfgFmt8583Ebo fmt8583 : fmt8583s) {
					org.w3c.dom.Element fmt8583Node = document.createElement("fmt");
					fmt8583Node.setAttribute("sequn", fmt8583.getSequn().toString());
					fmt8583Node.setAttribute("subSeq", fmt8583.getSubSeq());
					fmt8583Node.setAttribute("position", fmt8583.getPosition());
					fmt8583Node.setAttribute("name", fmt8583.getName());
					fmt8583Node.setAttribute("fldType", fmt8583.getFldType());
					fmt8583Node.setAttribute("length", fmt8583.getLength());
					fmt8583Node.setAttribute("memo", fmt8583.getMemo());
					fmt8583Node.setAttribute("varLen", fmt8583.getVarLen().toString());
					fmt8583Node.setAttribute("basLen", fmt8583.getBasLen().toString());
					fmtsNode.appendChild(fmt8583Node);
				}
			}
			return XmlHelper.buildXML(XmlHelper.parse(document), "UTF-8");
		} catch (ParserConfigurationException pe) {
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// 导入格式协议及格式定义
	public void putFmtByXML(String fmtXML) throws AppException {
		try {
			Document doc = XmlHelper.toW3CDocument(XmlHelper.buildDoc(fmtXML, "UTF-8"));
			NodeList formatList = doc.getElementsByTagName("format");
			int formatsize = formatList.getLength();
			for (int i = 0; i < formatsize; i++) {
				Element format = (Element) formatList.item(i);
				// System.out.println("[FMTS]" + format.getAttribute("name"));
				TCfgFormatEbo formatEbo = new TCfgFormatEbo();
				formatEbo.setName(format.getAttribute("name"));
				// formatEbo.setType(format.getAttribute("type"));
				formatEbo.setFmtver(format.getAttribute("fmtver"));
				formatEbo.setDescription(format.getAttribute("description"));
				formatEbo.setDelim(format.getAttribute("delim"));
				formatEbo.setFormat(format.getAttribute("format"));
				// formatEbo.setPathOpid(format.getAttribute("pathOpid"));
				// formatEbo.setConfig(format.getAttribute("config"));
				save(formatEbo);

				NodeList fmtList = doc.getElementsByTagName("fmt");
				int fmtsize = fmtList.getLength();
				for (int j = 0; j < fmtsize; j++) {
					Element fmt = (Element) fmtList.item(j);
					TCfgFmt8583Ebo f8583Ebo = new TCfgFmt8583Ebo();
					f8583Ebo.setTCfgFormat(formatEbo);
					f8583Ebo.setSequn(new Integer(fmt.getAttribute("sequn")));
					f8583Ebo.setSubSeq(fmt.getAttribute("subSeq"));
					f8583Ebo.setPosition(fmt.getAttribute("position"));
					f8583Ebo.setName(fmt.getAttribute("name"));
					f8583Ebo.setFldType(fmt.getAttribute("fldType"));
					f8583Ebo.setLength(fmt.getAttribute("length"));
					f8583Ebo.setMemo(fmt.getAttribute("memo"));
					f8583Ebo.setVarLen(new Integer(fmt.getAttribute("varLen")));
					f8583Ebo.setBasLen(new Integer(fmt.getAttribute("basLen")));
					save(f8583Ebo);
					// System.out.println("[FMT]" + fmt.getAttribute("name"));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void addFormat(TCfgFormatEbo o) throws AppException {
		// TODO Auto-generated method stub
		save(o);
	}

	public void editFormat(TCfgFormatEbo o) throws AppException {
		// TODO Auto-generated method stub
		saveOrUpdate(o);
	}

	// 获得8583格式明细
	public List<TCfgFmt8583Ebo> getAllFmt8583(Integer fmtOId, String fmtName) throws AppException {
		String hql = " from TCfgFmt8583Ebo t ";
		String where = "";
		if (fmtOId != null && fmtOId.intValue() > 0)
			where += " and t.TCfgFormat.oid = " + fmtOId;
		if (StringUtil.isNotNullStr(fmtName))
			where += " and t.TCfgFormat.name = '" + fmtName + "'";
		List<Object> paramList = new ArrayList<Object>();
		if (isNotBlank(where)) {
			where = " where " + where.substring(4);
		}
		hql = hql + where + " order by t.sequn";
		return find(hql, paramList.toArray());
	}

	//获得XML格式定义
	public List<TCfgFmtXmlEbo> getAllFmtXML(Integer fmtOId,String fmtName) throws AppException{
		String hql = " from TCfgFmtXmlEbo t ";
		String where = "";
		if (fmtOId != null && fmtOId.intValue() > 0)
			where += " and t.TCfgFormat.oid = " + fmtOId;
		if (StringUtil.isNotNullStr(fmtName))
			where += " and t.TCfgFormat.name = '" + fmtName + "'";
		List<Object> paramList = new ArrayList<Object>();
		if (isNotBlank(where)) {
			where = " where " + where.substring(4);
		}
		hql = hql + where;
		return find(hql, paramList.toArray());		
	}
	
	// 获得位置对应序列号
	// fmtOId=format对应的主键，pos=位置名称
	public String getPosSequn(Integer fmtOId,String pos) throws AppException{
		TCfgFormatEbo format = (TCfgFormatEbo)get(TCfgFormatEbo.class,fmtOId);
		if(format==null)
			throw new AppException("[找不到对于的格式对象]FmtOID="+fmtOId);
		//如果是8583格式
		if(format.getFormat().equals("8583")){
			String hql = "select f.sequn from TCfgFmt8583Ebo f where f.TCfgFormat.oid = " + fmtOId;
			hql += " and f.position ='" + pos + "'";
			List<Integer> fmts = find(hql);
			if(fmts.size() == 1)
				return fmts.get(0).toString();
			else
				throw new AppException("[找不到对于的位置]FmtOID="+fmtOId+",POSITION=" + pos);
		}else
			throw new AppException("[目前只支持8583格式的查找]");
	}
	
}
